home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / libhfs_iso / data.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-06  |  7.8 KB  |  371 lines

  1. /*
  2.  * hfsutils - tools for reading and writing Macintosh HFS volumes
  3.  * Copyright (C) 1996, 1997 Robert Leslie
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <mconfig.h>
  21. #include <strdefs.h>
  22. #include <time.h>
  23.  
  24. #include "internal.h"
  25. #include "data.h"
  26. #include "btree.h"
  27.  
  28. #define MUTDIFF    2082844800L
  29. #define    TZNONE    0x0FFFFFFFL    /* A timezone diff that cannot occur */
  30.  
  31. static    void    calctzdiff    __PR((void));
  32.  
  33. static
  34. unsigned long tzdiff = TZNONE;
  35.  
  36. unsigned char hfs_charorder[256] = {
  37.   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  38.   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  39.   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  40.   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  41.  
  42.   0x20, 0x22, 0x23, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
  43.   0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
  44.   0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
  45.   0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
  46.  
  47.   0x47, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69,
  48.   0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f,
  49.   0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1,
  50.   0xa3, 0xa5, 0xa8, 0xaa, 0xab, 0xac, 0xad, 0xae,
  51.  
  52.   0x54, 0x48, 0x58, 0x5a, 0x5e, 0x60, 0x67, 0x69,
  53.   0x6b, 0x6d, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7f,
  54.   0x8d, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9f, 0xa1,
  55.   0xa3, 0xa5, 0xa8, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
  56.  
  57.   0x4c, 0x50, 0x5c, 0x62, 0x7d, 0x81, 0x9a, 0x55,
  58.   0x4a, 0x56, 0x4c, 0x4e, 0x50, 0x5c, 0x62, 0x64,
  59.   0x65, 0x66, 0x6f, 0x70, 0x71, 0x72, 0x7d, 0x89,
  60.   0x8a, 0x8b, 0x81, 0x83, 0x9c, 0x9d, 0x9e, 0x9a,
  61.  
  62.   0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0x95,
  63.   0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0x52, 0x85,
  64.   0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
  65.   0xc9, 0xca, 0xcb, 0x57, 0x8c, 0xcc, 0x52, 0x85,
  66.  
  67.   0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0x26,
  68.   0x27, 0xd4, 0x20, 0x4a, 0x4e, 0x83, 0x87, 0x87,
  69.   0xd5, 0xd6, 0x24, 0x25, 0x2d, 0x2e, 0xd7, 0xd8,
  70.   0xa7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  71.  
  72.   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  73.   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  74.   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  75.   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  76. };
  77.  
  78. /*
  79.  * NAME:    data->getb()
  80.  * DESCRIPTION:    marshal 1 byte into local host format
  81.  */
  82. char d_getb(ptr)
  83.     unsigned char    *ptr;
  84. {
  85.   return (char) ptr[0];
  86. }
  87.  
  88. /*
  89.  * NAME:    data->getw()
  90.  * DESCRIPTION:    marshal 2 bytes into local host format
  91.  */
  92. short d_getw(ptr)
  93.     unsigned char    *ptr;
  94. {
  95.   return (short)
  96.     ((ptr[0] << 8) |
  97.      (ptr[1] << 0));
  98. }
  99.  
  100. /*
  101.  * NAME:    data->getl()
  102.  * DESCRIPTION:    marshal 4 bytes into local host format
  103.  */
  104. long d_getl(ptr)
  105.     unsigned char    *ptr;
  106. {
  107.   return (long)
  108.     ((ptr[0] << 24) |
  109.      (ptr[1] << 16) |
  110.      (ptr[2] <<  8) |
  111.      (ptr[3] <<  0));
  112. }
  113.  
  114. /*
  115.  * NAME:    data->putb()
  116.  * DESCRIPTION:    marshal 1 byte out to Macintosh (big-endian) format
  117.  */
  118. #ifdef    PROTOTYPES
  119. void d_putb(unsigned char *ptr, char data)
  120. #else
  121. void d_putb(ptr, data)
  122.     unsigned char    *ptr;
  123.     char        data;
  124. #endif
  125. {
  126.   ptr[0] = (unsigned char) data;
  127. }
  128.  
  129. /*
  130.  * NAME:    data->putw()
  131.  * DESCRIPTION:    marshal 2 bytes out to Macintosh (big-endian) format
  132.  */
  133. #ifdef    PROTOTYPES
  134. void d_putw(unsigned char *ptr, short data)
  135. #else
  136. void d_putw(ptr, data)
  137.     unsigned char    *ptr;
  138.     short        data;
  139. #endif
  140. {
  141.   ptr[0] = ((unsigned short) data & 0xff00) >> 8;
  142.   ptr[1] = ((unsigned short) data & 0x00ff) >> 0;
  143. }
  144.  
  145. /*
  146.  * NAME:    data->putl()
  147.  * DESCRIPTION:    marshal 4 bytes out to Macintosh (big-endian) format
  148.  */
  149. void d_putl(ptr, data)
  150.     unsigned char    *ptr;
  151.     long        data;
  152. {
  153.   ptr[0] = ((unsigned long) data & 0xff000000) >> 24;
  154.   ptr[1] = ((unsigned long) data & 0x00ff0000) >> 16;
  155.   ptr[2] = ((unsigned long) data & 0x0000ff00) >>  8;
  156.   ptr[3] = ((unsigned long) data & 0x000000ff) >>  0;
  157. }
  158.  
  159. /*
  160.  * NAME:    data->fetchb()
  161.  * DESCRIPTION:    incrementally retrieve a byte of data
  162.  */
  163. void d_fetchb(ptr, dest)
  164.     unsigned char    **ptr;
  165.     char        *dest;
  166. {
  167.   *dest = d_getb(*ptr);
  168.   *ptr += 1;
  169. }
  170.  
  171. /*
  172.  * NAME:    data->fetchw()
  173.  * DESCRIPTION:    incrementally retrieve a word of data
  174.  */
  175. void d_fetchw(ptr, dest)
  176.     unsigned char    **ptr;
  177.     short        *dest;
  178. {
  179.   *dest = d_getw(*ptr);
  180.   *ptr += 2;
  181. }
  182.  
  183. /*
  184.  * NAME:    data->fetchl()
  185.  * DESCRIPTION:    incrementally retrieve a long word of data
  186.  */
  187. void d_fetchl(ptr, dest)
  188.     unsigned char    **ptr;
  189.     long        *dest;
  190. {
  191.   *dest = d_getl(*ptr);
  192.   *ptr += 4;
  193. }
  194.  
  195. /*
  196.  * NAME:    data->fetchs()
  197.  * DESCRIPTION:    incrementally retrieve a string
  198.  */
  199. void d_fetchs(ptr, dest, size)
  200.     unsigned char    **ptr;
  201.     char        *dest;
  202.     int        size;
  203. {
  204.   int len;
  205.   char blen;
  206.  
  207.   d_fetchb(ptr, &blen);
  208.   len = blen;
  209.  
  210.   if (len > 0 && len < size)
  211.     memcpy(dest, *ptr, len);
  212.   else
  213.     len = 0;
  214.  
  215.   dest[len] = 0;
  216.  
  217.   *ptr += size - 1;
  218. }
  219.  
  220. /*
  221.  * NAME:    data->storeb()
  222.  * DESCRIPTION:    incrementally store a byte of data
  223.  */
  224. #ifdef    PROTOTYPES
  225. void d_storeb(unsigned char **ptr, char data)
  226. #else
  227. void d_storeb(ptr, data)
  228.     unsigned char    **ptr;
  229.     char        data;
  230. #endif
  231. {
  232.   d_putb(*ptr, data);
  233.   *ptr += 1;
  234. }
  235.  
  236. /*
  237.  * NAME:    data->storew()
  238.  * DESCRIPTION:    incrementally store a word of data
  239.  */
  240. #ifdef    PROTOTYPES
  241. void d_storew(unsigned char **ptr, short data)
  242. #else
  243. void d_storew(ptr, data)
  244.     unsigned char    **ptr;
  245.     short        data;
  246. #endif
  247. {
  248.   d_putw(*ptr, data);
  249.   *ptr += 2;
  250. }
  251.  
  252. /*
  253.  * NAME:    data->storel()
  254.  * DESCRIPTION:    incrementally store a long word of data
  255.  */
  256. void d_storel(ptr, data)
  257.     unsigned char    **ptr;
  258.     long        data;
  259. {
  260.   d_putl(*ptr, data);
  261.   *ptr += 4;
  262. }
  263.  
  264. /*
  265.  * NAME:    data->stores()
  266.  * DESCRIPTION:    incrementally store a string
  267.  */
  268. void d_stores(ptr, src, size)
  269.     unsigned char    **ptr;
  270.     char        *src;
  271.     int        size;
  272. {
  273.   int len;
  274.  
  275.   len = strlen(src);
  276.   if (len > --size)
  277.     len = 0;
  278.  
  279.   d_storeb(ptr, (unsigned char) len);
  280.  
  281.   memcpy(*ptr, src, len);
  282.   memset(*ptr + len, 0, size - len);
  283.  
  284.   *ptr += size;
  285. }
  286.  
  287. /*
  288.  * NAME:    calctzdiff()
  289.  * DESCRIPTION:    calculate the timezone difference between local time and UTC
  290.  */
  291. static
  292. void calctzdiff()
  293. {
  294.   time_t t;
  295.   int isdst;
  296.   struct tm tm, *tmp;
  297.  
  298.   time(&t);
  299.   isdst = localtime(&t)->tm_isdst;
  300.  
  301.   tmp = gmtime(&t);
  302.   if (tmp)
  303.     {
  304.       tm = *tmp;
  305.       tm.tm_isdst = isdst;
  306.  
  307.       tzdiff = t - mktime(&tm);
  308.     }
  309.   else
  310.     tzdiff = 0;
  311. }
  312.  
  313. /*
  314.  * NAME:    data->tomtime()
  315.  * DESCRIPTION:    convert UNIX time to Macintosh time
  316.  */
  317. unsigned long d_tomtime(secs)
  318.     unsigned long    secs;
  319. {
  320.   time_t utime = secs;
  321.  
  322.   if (tzdiff == TZNONE)
  323.     calctzdiff();
  324.  
  325.   return utime + tzdiff + MUTDIFF;
  326. }
  327.  
  328. /*
  329.  * NAME:    data->toutime()
  330.  * DESCRIPTION:    convert Macintosh time to UNIX time
  331.  */
  332. unsigned long d_toutime(secs)
  333.     unsigned long    secs;
  334. {
  335.   time_t utime = secs;
  336.  
  337.   if (tzdiff == TZNONE)
  338.     calctzdiff();
  339.  
  340.   return utime - MUTDIFF - tzdiff;
  341. }
  342.  
  343. /*
  344.  * NAME:    data->relstring()
  345.  * DESCRIPTION:    compare two strings as per MacOS for HFS
  346.  */
  347. int d_relstring(str1, str2)
  348.     char    *str1;
  349.     char    *str2;
  350. {
  351.   int diff;
  352.  
  353.   while (*str1 && *str2)
  354.     {
  355.       diff = hfs_charorder[(unsigned char) *str1] -
  356.          hfs_charorder[(unsigned char) *str2];
  357.  
  358.       if (diff)
  359.     return diff;
  360.  
  361.       ++str1, ++str2;
  362.     }
  363.  
  364.   if (! *str1 && *str2)
  365.     return -1;
  366.   else if (*str1 && ! *str2)
  367.     return 1;
  368.  
  369.   return 0;
  370. }
  371.